package munci.old.know.words;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import munci.old.know.Env;
import munci.old.use.Try;


public class MetaWord extends Word {

	@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)
	public @interface Name {
	    String value();
	}

	public static Word.Book all(Word.Book list) {
		for (Method m : list.source().getDeclaredMethods()) {
			if (m.isAnnotationPresent(MetaWord.Name.class)) {
				list.add(new MetaWord(m.getAnnotation(MetaWord.Name.class).value(), m));
			}
		}
		return list;
	}

	private final Method method;
	
	public MetaWord(String name, Method method) {
		super(name);
		this.method = method;
	}

	public boolean execute(Env env) {
		if (boolean.class.equals(method.getReturnType())) {
			return (Boolean) Try.invoke(method, null, env);
		} else {
			Try.invoke(method, null, env);
			return true;
		}
	}

	@Override public String toString() {
		return super.toString() + " meta: " + method.getDeclaringClass().getSimpleName() + '.' + method.getName();
	}
}
